﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.Common;

namespace EFMassOperations
{
	static class DbParameterHelper
	{
		static Dictionary<Type,DbType> nullableTypeMap = new Dictionary<Type, DbType>();
		static Dictionary<Type, DbType> nonNullableTypeMap = new Dictionary<Type, DbType>();

		static DbParameterHelper()
		{
			nullableTypeMap[typeof(byte)] = DbType.Byte;
			nullableTypeMap[typeof(sbyte)] = DbType.SByte;
			nullableTypeMap[typeof(short)] = DbType.Int16;
			nullableTypeMap[typeof(ushort)] = DbType.UInt16;
			nullableTypeMap[typeof(int)] = DbType.Int32;
			nullableTypeMap[typeof(uint)] = DbType.UInt32;
			nullableTypeMap[typeof(long)] = DbType.Int64;
			nullableTypeMap[typeof(ulong)] = DbType.UInt64;
			nullableTypeMap[typeof(float)] = DbType.Single;
			nullableTypeMap[typeof(double)] = DbType.Double;
			nullableTypeMap[typeof(decimal)] = DbType.Decimal;
			nullableTypeMap[typeof(bool)] = DbType.Boolean;
			nullableTypeMap[typeof(char)] = DbType.StringFixedLength;
			nullableTypeMap[typeof(Guid)] = DbType.Guid;
			nullableTypeMap[typeof(DateTime)] = DbType.DateTime;
			nullableTypeMap[typeof(DateTimeOffset)] = DbType.DateTimeOffset;
			
			nonNullableTypeMap[typeof(byte[])] = DbType.Binary;
			nonNullableTypeMap[typeof(string)] = DbType.String;
			//typeMap[typeof(System.Data.Linq.Binary)] = DbType.Binary;
		}


		public static bool TryGetDbType(Type type, out DbType dbType)
		{
			Type t = type;
			if (nonNullableTypeMap.ContainsKey(t))
			{
				dbType = nonNullableTypeMap[t];
				return true;
			}
			if (t.IsGenericType && t.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
				t = t.GetGenericArguments()[0];
			if (nullableTypeMap.ContainsKey(t))
			{
				dbType = nullableTypeMap[t];
				return true;
			}
			dbType = (DbType)int.MaxValue;
			return false;
		}

		public static void SetParameterValue(DbParameter parameter, object value, bool applyNullConversion)
		{
			if (value == null && applyNullConversion)
				parameter.Value = DBNull.Value;
			else
				parameter.Value = value;
		}
	}
}
